package cz.vutbr.fit.xzemko01.tfmcbs.validation.validators;

import java.util.Map;

import org.eclipse.emf.common.util.Diagnostic;
import org.eclipse.emf.common.util.DiagnosticChain;

import cz.vutbr.fit.xzemko01.tfmcbs.model.Component;
import cz.vutbr.fit.xzemko01.tfmcbs.model.Entity;
import cz.vutbr.fit.xzemko01.tfmcbs.model.Generalization;
import cz.vutbr.fit.xzemko01.tfmcbs.model.Relationship;
import cz.vutbr.fit.xzemko01.tfmcbs.validation.utils.DiagnosticBuilder;

public final class GeneralizationValidator implements Validator<Generalization> {
	
	private static GeneralizationValidator generalizationValidator;
	
	private Validator<Relationship> relationshipValidator;
	
	private GeneralizationValidator() {
		relationshipValidator = RelationshipValidator.getInstance();
	}
	
	public static Validator<Generalization> getInstance() {
		if(generalizationValidator == null) {
			generalizationValidator = new GeneralizationValidator();
		}
		return generalizationValidator;
	}

	@Override
	public boolean validate(Generalization generalization, DiagnosticChain diagnostics, Map<Object, Object> context) {
		boolean result = relationshipValidator.validate(generalization, diagnostics, context);
		result &= validateGeneralizationEnds(generalization, diagnostics, context);
		return result;
	}
	
	private boolean validateGeneralizationEnds(Generalization generalization, DiagnosticChain diagnostics, Map<Object, Object> context) {
		Entity childEntity = generalization.getChild();
		Entity parentEntity = generalization.getParent();
		
		if(childEntity == null) {
			Diagnostic diagnostic = new DiagnosticBuilder(generalization)
						.setMessage("Generalization \"" + generalization.getName() + "\" has no child entity.").build();
			diagnostics.add(diagnostic);
			return false;
		} else if(parentEntity == null) {
			Diagnostic diagnostic = new DiagnosticBuilder(generalization)
						.setMessage("Generalization \"" + generalization.getName() + "\" has no parent entity.").build();
			diagnostics.add(diagnostic);
			return false;
		} else if(childEntity.getClass() != parentEntity.getClass()
				&& !(childEntity instanceof Component && parentEntity instanceof Component)) 
		{
			String errorMessage = "Generalization \"" + generalization.getName() 
									+ "\" must have parent and child entity same type.";
			Diagnostic diagnostic = new DiagnosticBuilder(generalization).setMessage(errorMessage).build();
			diagnostics.add(diagnostic);
			return false;
		}
		return true;		 
	}
}
